home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagd_aux.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  24.2 KB  |  799 lines

  1. /******************************************************************************
  2. * Cagd_aux.c - auxiliary routine to interface to different free from types.   *
  3. *******************************************************************************
  4. * Written by Gershon Elber, July. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /******************************************************************************
  10. * Given a curve, returns its parametric domain.                      *
  11. ******************************************************************************/
  12. void CagdCrvDomain(CagdCrvStruct *Crv, CagdRType *TMin, CagdRType *TMax)
  13. {
  14.     switch (Crv -> GType) {
  15.     case CAGD_CBEZIER_TYPE:
  16.         *TMin = 0.0;
  17.         *TMax = 1.0;
  18.         break;
  19.     case CAGD_CBSPLINE_TYPE:
  20.         BspCrvDomain(Crv, TMin, TMax);
  21.         break;
  22.     case CAGD_CPOWER_TYPE:
  23.     default:
  24.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  25.         break;
  26.     }
  27. }
  28.  
  29. /******************************************************************************
  30. * Given a crv and parameter value t, evaluate the curve at t.              *
  31. ******************************************************************************/
  32. CagdRType *CagdCrvEval(CagdCrvStruct *Crv, CagdRType t)
  33. {
  34.     switch (Crv -> GType) {
  35.     case CAGD_CBEZIER_TYPE:
  36.         return BzrCrvEvalAtParam(Crv, t);
  37.     case CAGD_CBSPLINE_TYPE:
  38.         return BspCrvEvalAtParam(Crv, t);
  39.     case CAGD_CPOWER_TYPE:
  40.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  41.         return NULL;
  42.     default:
  43.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  44.         return NULL;
  45.     }
  46. }
  47.  
  48. /******************************************************************************
  49. * Given a surface, returns its parametric domain.                  *
  50. ******************************************************************************/
  51. void CagdSrfDomain(CagdSrfStruct *Srf, CagdRType *UMin, CagdRType *UMax,
  52.                        CagdRType *VMin, CagdRType *VMax)
  53. {
  54.     switch (Srf -> GType) {
  55.     case CAGD_SBEZIER_TYPE:
  56.         *UMin = 0.0;
  57.         *UMax = 1.0;
  58.         *VMin = 0.0;
  59.         *VMax = 1.0;
  60.         break;
  61.     case CAGD_SBSPLINE_TYPE:
  62.         BspSrfDomain(Srf, UMin, UMax, VMin, VMax);
  63.         break;
  64.     case CAGD_SPOWER_TYPE:
  65.     default:
  66.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  67.         break;
  68.     }
  69. }
  70.  
  71. /******************************************************************************
  72. * Given a srf and parameter values u,v, evaluate the surface at u,v.          *
  73. ******************************************************************************/
  74. CagdRType *CagdSrfEval(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  75. {
  76.     switch (Srf -> GType) {
  77.     case CAGD_SBEZIER_TYPE:
  78.         return BzrSrfEvalAtParam(Srf, u, v);
  79.     case CAGD_SBSPLINE_TYPE:
  80.         return BspSrfEvalAtParam(Srf, u, v);
  81.     case CAGD_SPOWER_TYPE:
  82.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  83.         return NULL;
  84.     default:
  85.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  86.         return NULL;
  87.     }
  88. }
  89.  
  90. /******************************************************************************
  91. * Given a curve, compute its derivative curve.                      *
  92. ******************************************************************************/
  93. CagdCrvStruct *CagdCrvDerive(CagdCrvStruct *Crv)
  94. {
  95.     switch (Crv -> GType) {
  96.     case CAGD_CBEZIER_TYPE:
  97.         return BzrCrvDerive(Crv);
  98.     case CAGD_CBSPLINE_TYPE:
  99.         return BspCrvDerive(Crv);
  100.     case CAGD_CPOWER_TYPE:
  101.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  102.         return NULL;
  103.     default:
  104.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  105.         return NULL;
  106.     }
  107. }
  108.  
  109. /******************************************************************************
  110. * Given a curve, compute its integral as a curve.                  *
  111. ******************************************************************************/
  112. CagdCrvStruct *CagdCrvIntegrate(CagdCrvStruct *Crv)
  113. {
  114.     switch (Crv -> GType) {
  115.     case CAGD_CBEZIER_TYPE:
  116.         return BzrCrvIntegrate(Crv);
  117.     case CAGD_CBSPLINE_TYPE:
  118.         return BspCrvIntegrate(Crv);
  119.     case CAGD_CPOWER_TYPE:
  120.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  121.         return NULL;
  122.     default:
  123.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  124.         return NULL;
  125.     }
  126. }
  127.  
  128. /******************************************************************************
  129. * Given a planar curve, compute its enclosed area as a curve.              *
  130. ******************************************************************************/
  131. CagdCrvStruct *CagdCrvEnclosedArea(CagdCrvStruct *Crv)
  132. {
  133.     CagdVType Trans;
  134.     CagdCrvStruct *CrvX, *CrvY, *CrvZ, *CrvW, *DCrvX, *DCrvY,
  135.     *CTmp1, *CTmp2, *CTmp3;
  136.  
  137.     switch (Crv -> GType) {
  138.     case CAGD_CBEZIER_TYPE:
  139.     case CAGD_CBSPLINE_TYPE:
  140.         break;
  141.     case CAGD_CPOWER_TYPE:
  142.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  143.         return NULL;
  144.     default:
  145.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  146.         return NULL;
  147.     }
  148.  
  149.     /* Using Green's theorem, if C(t1) = C(t2) the area enclosed is equal to */
  150.     /*                                         */
  151.     /*       t2                                     */
  152.     /*        /                                     */
  153.     /*    1  |                                     */
  154.     /*  -  | -x'(t) y(t) + x(t) y'(t) dt                     */
  155.     /*    2  |                                     */
  156.     /*    /                                     */
  157.     /*    t1                                     */
  158.     /*                                         */
  159.     CagdCrvSplitScalar(Crv, &CrvW, &CrvX, &CrvY, &CrvZ);
  160.     if (CrvZ)
  161.         CagdCrvFree(CrvZ);
  162.     if (CrvW) {
  163.     FATAL_ERROR(CAGD_ERR_RATIONAL_NO_SUPPORT);
  164.     CagdCrvFree(CrvW);
  165.     }
  166.  
  167.     DCrvX = CagdCrvDerive(CrvX);
  168.     DCrvY = CagdCrvDerive(CrvY);
  169.     CTmp1 = CagdCrvMult(CrvX, DCrvY);
  170.     CTmp2 = CagdCrvMult(DCrvX, CrvY);
  171.     CagdCrvFree(CrvX);
  172.     CagdCrvFree(CrvY);
  173.     CagdCrvFree(DCrvX);
  174.     CagdCrvFree(DCrvY);
  175.     CTmp3 = CagdCrvSub(CTmp1, CTmp2);
  176.     CagdCrvFree(CTmp1);
  177.     CagdCrvFree(CTmp2);
  178.     CTmp1 = CagdCrvIntegrate(CTmp3);
  179.     CagdCrvFree(CTmp3);
  180.  
  181.     /* Scale by a half. */
  182.     Trans[0] = Trans[1] = Trans[2] = 0.0;
  183.     CagdCrvTransform(CTmp1, Trans, 0.5);
  184.  
  185.     return CTmp1;
  186. }
  187.  
  188. /******************************************************************************
  189. * Given a surface, compute its partial derivative surface in direction Dir.   *
  190. ******************************************************************************/
  191. CagdSrfStruct *CagdSrfDerive(CagdSrfStruct *Srf, CagdSrfDirType Dir)
  192. {
  193.     switch (Srf -> GType) {
  194.     case CAGD_SBEZIER_TYPE:
  195.         return BzrSrfDerive(Srf, Dir);
  196.     case CAGD_SBSPLINE_TYPE:
  197.         return BspSrfDerive(Srf, Dir);
  198.     case CAGD_SPOWER_TYPE:
  199.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  200.         return NULL;
  201.     default:
  202.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  203.         return NULL;
  204.     }
  205. }
  206.  
  207. /******************************************************************************
  208. * Given a curve - subdivide it into two at the given parametric value.        *
  209. * Returns pointer to first curve in a list of two curves (subdivided ones).   *
  210. ******************************************************************************/
  211. CagdCrvStruct *CagdCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t)
  212. {
  213.     switch (Crv -> GType) {
  214.     case CAGD_CBEZIER_TYPE:
  215.         return BzrCrvSubdivAtParam(Crv, t);
  216.     case CAGD_CBSPLINE_TYPE:
  217.         return BspCrvSubdivAtParam(Crv, t);
  218.     case CAGD_CPOWER_TYPE:
  219.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  220.         return NULL;
  221.     default:
  222.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  223.         return NULL;
  224.     }
  225. }
  226.  
  227. /******************************************************************************
  228. * Given a curve - returns a sub region within the specified domain.           *
  229. ******************************************************************************/
  230. CagdCrvStruct *CagdCrvRegionFromCrv(CagdCrvStruct *Crv, CagdRType t1,
  231.                             CagdRType t2)
  232. {
  233.     CagdRType TMin, TMax;
  234.     CagdCrvStruct *Crvs;
  235.     CagdBType
  236.     NewCrv = FALSE;
  237.  
  238.     switch (Crv -> GType) {
  239.     case CAGD_CBEZIER_TYPE:
  240.         TMin = 0.0;
  241.         TMax = 1.0;
  242.         break;
  243.     case CAGD_CBSPLINE_TYPE:
  244.             BspCrvDomain(Crv, &TMin, &TMax);
  245.         break;
  246.     case CAGD_CPOWER_TYPE:
  247.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  248.         return NULL;
  249.     default:
  250.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  251.         return NULL;
  252.     }
  253.  
  254.     if (t1 > t2)
  255.     SWAP(CagdRType, t1, t2);
  256.  
  257.     if (!APX_EQ(t1, TMin)) {
  258.         Crvs = CagdCrvSubdivAtParam(Crv, t1);
  259.     Crv = Crvs -> Pnext;
  260.     Crvs -> Pnext = NULL;
  261.     CagdCrvFree(Crvs);               /* Free the first region. */
  262.     NewCrv = TRUE;
  263.     }
  264.  
  265.     if (APX_EQ(t2, TMax))
  266.     return NewCrv ? Crv : CagdCrvCopy(Crv);
  267.     else {
  268.     Crvs = CagdCrvSubdivAtParam(Crv, t2);
  269.  
  270.     if (NewCrv)
  271.         CagdCrvFree(Crv);
  272.  
  273.         CagdCrvFree(Crvs -> Pnext);          /* Free the second region. */
  274.         Crvs -> Pnext = NULL;
  275.         return Crvs;                /* Returns the first region. */
  276.     }
  277. }
  278.  
  279. /******************************************************************************
  280. * Given a curve - refine it at the given n knots as defined by vector t.      *
  281. * If Replace is TRUE, the values replaces current vector instead.          *
  282. * Returns pointer to refined crv (Note Bezier will be converted into spline). *
  283. ******************************************************************************/
  284. CagdCrvStruct *CagdCrvRefineAtParams(CagdCrvStruct *Crv, CagdBType Replace,
  285.                              CagdRType *t, int n)
  286. {
  287.     CagdCrvStruct *BspCrv, *TCrv;
  288.  
  289.     switch (Crv -> GType) {
  290.     case CAGD_CBEZIER_TYPE:
  291.             BspCrv = CnvrtBezier2BsplineCrv(Crv);
  292.         TCrv = BspCrvKnotInsertNDiff(BspCrv, Replace, t, n);
  293.         CagdCrvFree(BspCrv);
  294.         return TCrv;
  295.     case CAGD_CBSPLINE_TYPE:
  296.         return BspCrvKnotInsertNDiff(Crv, Replace, t, n);
  297.     case CAGD_CPOWER_TYPE:
  298.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  299.         return NULL;
  300.     default:
  301.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  302.         return NULL;
  303.     }
  304. }
  305.  
  306. /******************************************************************************
  307. * Return a new curve reversed by reversing the ctl polygon.                   *
  308. ******************************************************************************/
  309. CagdCrvStruct *CagdCrvReverse(CagdCrvStruct *Crv)
  310. {
  311.     CagdBType
  312.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  313.     int i, Len, Col,
  314.     Length = Crv -> Length,
  315.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  316.     CagdCrvStruct
  317.         *ReversedCrv = CagdCrvCopy(Crv);
  318.     CagdRType *KV,
  319.     **Points = ReversedCrv -> Points;
  320.  
  321.     switch (Crv -> GType) {
  322.     case CAGD_CBEZIER_TYPE:
  323.     case CAGD_CBSPLINE_TYPE:
  324.         break;
  325.     case CAGD_CPOWER_TYPE:
  326.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  327.         return NULL;
  328.     default:
  329.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  330.         return NULL;
  331.     }
  332.  
  333.     /* Reverse the Ctl Polygon: */
  334.     Len = Length / 2;
  335.     for (Col = 0; Col < Len; Col++)
  336.     for (i = IsNotRational; i <= MaxCoord; i++)
  337.         SWAP(CagdRType,
  338.          Points[i][Col],
  339.          Points[i][Length - Col - 1]);
  340.  
  341.     /* Reverse the knot vector if it exists: */
  342.     if (Crv -> GType == CAGD_CBSPLINE_TYPE &&
  343.     Crv -> KnotVector != NULL) {
  344.     KV = BspKnotReverse(Crv -> KnotVector, Crv -> Order + Length);
  345.     IritFree((VoidPtr) ReversedCrv -> KnotVector);
  346.     ReversedCrv -> KnotVector = KV;
  347.     }
  348.  
  349.     return ReversedCrv;
  350. }
  351.  
  352. /******************************************************************************
  353. * Return a new curve representing the same curve but with degree raised.      *
  354. ******************************************************************************/
  355. CagdCrvStruct *CagdCrvDegreeRaise(CagdCrvStruct *Crv)
  356. {
  357.     switch (Crv -> GType) {
  358.     case CAGD_CBEZIER_TYPE:
  359.         return BzrCrvDegreeRaise(Crv);
  360.     case CAGD_CBSPLINE_TYPE:
  361.         return BspCrvDegreeRaise(Crv);
  362.     case CAGD_CPOWER_TYPE:
  363.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  364.         return NULL;
  365.     default:
  366.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  367.         return NULL;
  368.     }
  369. }
  370.  
  371. /******************************************************************************
  372. * Return a new curve representing the same curve but with degree raised.      *
  373. ******************************************************************************/
  374. CagdCrvStruct *CagdCrvDegreeRaiseN(CagdCrvStruct *Crv, int NewOrder)
  375. {
  376.     switch (Crv -> GType) {
  377.     case CAGD_CBEZIER_TYPE:
  378.         return BzrCrvDegreeRaiseN(Crv, NewOrder);
  379.     case CAGD_CBSPLINE_TYPE:
  380.         return BspCrvDegreeRaiseN(Crv, NewOrder);
  381.     case CAGD_CPOWER_TYPE:
  382.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  383.         return NULL;
  384.     default:
  385.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  386.         return NULL;
  387.     }
  388. }
  389.  
  390. /******************************************************************************
  391. * Return a new surface representing the same surface but with degree raised.  *
  392. ******************************************************************************/
  393. CagdSrfStruct *CagdSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir)
  394. {
  395.     switch (Srf -> GType) {
  396.     case CAGD_SBEZIER_TYPE:
  397.         return BzrSrfDegreeRaise(Srf, Dir);
  398.     case CAGD_SBSPLINE_TYPE:
  399.         return BspSrfDegreeRaise(Srf, Dir);
  400.     case CAGD_SPOWER_TYPE:
  401.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  402.         return NULL;
  403.     default:
  404.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  405.         return NULL;
  406.     }
  407. }
  408.  
  409. /******************************************************************************
  410. * Extracts an iso curve from the surface as spcified by Dir and t.          *
  411. ******************************************************************************/
  412. CagdCrvStruct *CagdCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
  413.                             CagdSrfDirType Dir)
  414. {
  415.     switch (Srf -> GType) {
  416.     case CAGD_SBEZIER_TYPE:
  417.         return BzrSrfCrvFromSrf(Srf, t, Dir);
  418.     case CAGD_SBSPLINE_TYPE:
  419.         return BspSrfCrvFromSrf(Srf, t, Dir);
  420.     case CAGD_SPOWER_TYPE:
  421.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  422.         return NULL;
  423.     default:
  424.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  425.         return NULL;
  426.     }
  427. }
  428.  
  429. /******************************************************************************
  430. * Extracts a curve from the surface as spcified by Dir and Index.          *
  431. *   The curve is constructed as a single ROW/COL of the original surface.     *
  432. *   Note this curve may be not on the surface!                      *
  433. ******************************************************************************/
  434. CagdCrvStruct *CagdCrvFromMesh(CagdSrfStruct *Srf, int Index,
  435.                             CagdSrfDirType Dir)
  436. {
  437.     switch (Srf -> GType) {
  438.     case CAGD_SBEZIER_TYPE:
  439.         return BzrSrfCrvFromMesh(Srf, Index, Dir);
  440.     case CAGD_SBSPLINE_TYPE:
  441.         return BspSrfCrvFromMesh(Srf, Index, Dir);
  442.     case CAGD_SPOWER_TYPE:
  443.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  444.         return NULL;
  445.     default:
  446.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  447.         return NULL;
  448.     }
  449. }
  450.  
  451. /******************************************************************************
  452. * Substitue a row/col from the given curve into the surface as spcified by    *
  453. * Dir and Index. Curve must have same PtType/Length and the surface row/col.  *
  454. ******************************************************************************/
  455. void CagdCrvToMesh(CagdCrvStruct *Crv, int Index,
  456.                     CagdSrfDirType Dir, CagdSrfStruct *Srf)
  457. {
  458.     CagdBType
  459.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  460.     int i, j,
  461.     Length = Crv -> Length,
  462.     ULength = Srf -> ULength,
  463.     VLength = Srf -> VLength,
  464.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  465.     CagdRType *CrvP, *SrfP;
  466.  
  467.     if (Crv -> PType != Srf -> PType ||
  468.     Length != (Dir == CAGD_CONST_U_DIR ? VLength : ULength))
  469.     FATAL_ERROR(CAGD_ERR_PT_OR_LEN_MISMATCH);
  470.  
  471.     switch (Dir) {
  472.     case CAGD_CONST_U_DIR:
  473.         if (Index + 1 > ULength)
  474.         FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  475.  
  476.         for (i = IsNotRational; i <= MaxCoord; i++) {
  477.         CrvP = Crv -> Points[i];
  478.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_U(Srf);
  479.         for (j = 0; j < Length; j++) {
  480.             *SrfP = *CrvP++;
  481.             SrfP += CAGD_NEXT_V(Srf);
  482.         }
  483.         }
  484.         break;
  485.     case CAGD_CONST_V_DIR:
  486.         if (Index + 1 > VLength)
  487.         FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
  488.  
  489.         for (i = IsNotRational; i <= MaxCoord; i++) {
  490.         CrvP = Crv -> Points[i];
  491.         SrfP = Srf -> Points[i] + Index * CAGD_NEXT_V(Srf);;
  492.         for (j = 0; j < Length; j++) {
  493.             *SrfP = *CrvP++;
  494.             SrfP += CAGD_NEXT_U(Srf);
  495.         }
  496.         }
  497.         break;
  498.     default:
  499.         FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
  500.         break;
  501.     }
  502. }
  503.  
  504. /******************************************************************************
  505. * Given a srf - subdivide it into two at given parametric value in given dir. *
  506. * Returns pointer to first srf in a list of two srfs (subdivided ones).       *
  507. ******************************************************************************/
  508. CagdSrfStruct *CagdSrfSubdivAtParam(CagdSrfStruct *Srf, CagdRType t,
  509.                                 CagdSrfDirType Dir)
  510. {
  511.     switch (Srf -> GType) {
  512.     case CAGD_SBEZIER_TYPE:
  513.         return BzrSrfSubdivAtParam(Srf, t, Dir);
  514.     case CAGD_SBSPLINE_TYPE:
  515.         return BspSrfSubdivAtParam(Srf, t, Dir);
  516.     case CAGD_SPOWER_TYPE:
  517.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  518.         return NULL;
  519.     default:
  520.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  521.         return NULL;
  522.     }
  523. }
  524.  
  525. /******************************************************************************
  526. * Given a surface - returns a sub region within the specified domain, dir.    *
  527. ******************************************************************************/
  528. CagdSrfStruct *CagdSrfRegionFromSrf(CagdSrfStruct *Srf, CagdRType t1,
  529.                           CagdRType t2, CagdSrfDirType Dir)
  530. {
  531.     CagdRType TMin, TMax, R1, R2;
  532.     CagdSrfStruct *Srfs;
  533.     CagdBType
  534.     NewSrf = FALSE;
  535.  
  536.     switch (Srf -> GType) {
  537.     case CAGD_SBEZIER_TYPE:
  538.         TMin = 0.0;
  539.         TMax = 1.0;
  540.         break;
  541.     case CAGD_SBSPLINE_TYPE:
  542.             if (Dir == CAGD_CONST_U_DIR)
  543.         BspSrfDomain(Srf, &TMin, &TMax, &R1, &R2);
  544.         else
  545.         BspSrfDomain(Srf, &R1, &R2, &TMin, &TMax);
  546.         break;
  547.     case CAGD_SPOWER_TYPE:
  548.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  549.         return NULL;
  550.     default:
  551.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  552.         return NULL;
  553.     }
  554.  
  555.     if (t1 > t2)
  556.     SWAP(CagdRType, t1, t2);
  557.  
  558.     if (!APX_EQ(t1, TMin)) {
  559.     Srfs = CagdSrfSubdivAtParam(Srf, t1, Dir);
  560.     Srf = Srfs -> Pnext;
  561.     Srfs -> Pnext = NULL;
  562.     CagdSrfFree(Srfs);               /* Free the first region. */
  563.     NewSrf = TRUE;
  564.     }
  565.  
  566.     if (APX_EQ(t2, TMax))
  567.     return NewSrf ? Srf : CagdSrfCopy(Srf);
  568.     else {
  569.     Srfs = CagdSrfSubdivAtParam(Srf, t2, Dir);
  570.  
  571.     if (NewSrf)
  572.         CagdSrfFree(Srf);
  573.  
  574.         CagdSrfFree(Srfs -> Pnext);          /* Free the second region. */
  575.         Srfs -> Pnext = NULL;
  576.     return Srfs;                /* Returns the first region. */
  577.     }
  578. }
  579.  
  580. /******************************************************************************
  581. * Given a surface - refine it at the given n knots as defined by vector t.    *
  582. * If Replace is TRUE, the values replaces current vector instead.          *
  583. * Returns pointer to refined srf (Note Bezier will be converted into spline). *
  584. ******************************************************************************/
  585. CagdSrfStruct *CagdSrfRefineAtParams(CagdSrfStruct *Srf, CagdSrfDirType Dir,
  586.                     CagdBType Replace, CagdRType *t, int n)
  587. {
  588.     CagdSrfStruct *BspSrf, *TSrf;
  589.  
  590.     switch (Srf -> GType) {
  591.     case CAGD_SBEZIER_TYPE:
  592.             BspSrf = CnvrtBezier2BsplineSrf(Srf);
  593.         TSrf = BspSrfKnotInsertNDiff(BspSrf, Dir, Replace, t, n);
  594.         CagdSrfFree(BspSrf);
  595.         return TSrf;
  596.     case CAGD_SBSPLINE_TYPE:
  597.         return BspSrfKnotInsertNDiff(Srf, Dir, Replace, t, n);
  598.     case CAGD_SPOWER_TYPE:
  599.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  600.         return NULL;
  601.     default:
  602.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  603.         return NULL;
  604.     }
  605. }
  606.  
  607. /******************************************************************************
  608. * Given a curve and a parameter value t, returns the tangent direction at t.  *
  609. ******************************************************************************/
  610. CagdVecStruct *CagdCrvTangent(CagdCrvStruct *Crv, CagdRType t)
  611. {
  612.     switch (Crv -> GType) {
  613.     case CAGD_CBEZIER_TYPE:
  614.         return BzrCrvTangent(Crv, t);
  615.     case CAGD_CBSPLINE_TYPE:
  616.         return BspCrvTangent(Crv, t);
  617.     case CAGD_CPOWER_TYPE:
  618.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  619.         return NULL;
  620.     default:
  621.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  622.         return NULL;
  623.     }
  624. }
  625.  
  626. /******************************************************************************
  627. * Given a curve and a parameter value t, returns the binormal direction at t. *
  628. ******************************************************************************/
  629. CagdVecStruct *CagdCrvBiNormal(CagdCrvStruct *Crv, CagdRType t)
  630. {
  631.     switch (Crv -> GType) {
  632.     case CAGD_CBEZIER_TYPE:
  633.         return BzrCrvBiNormal(Crv, t);
  634.     case CAGD_CBSPLINE_TYPE:
  635.         return BspCrvBiNormal(Crv, t);
  636.     case CAGD_CPOWER_TYPE:
  637.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  638.         return NULL;
  639.     default:
  640.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  641.         return NULL;
  642.     }
  643. }
  644.  
  645. /******************************************************************************
  646. * Given a curve and a parameter value t, returns the normal direction at t.   *
  647. ******************************************************************************/
  648. CagdVecStruct *CagdCrvNormal(CagdCrvStruct *Crv, CagdRType t)
  649. {
  650.     switch (Crv -> GType) {
  651.     case CAGD_CBEZIER_TYPE:
  652.         return BzrCrvNormal(Crv, t);
  653.     case CAGD_CBSPLINE_TYPE:
  654.         return BspCrvNormal(Crv, t);
  655.     case CAGD_CPOWER_TYPE:
  656.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  657.         return NULL;
  658.     default:
  659.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  660.         return NULL;
  661.     }
  662. }
  663.  
  664. /******************************************************************************
  665. * Given a srf and parameter value u,v, returns the tangent direction in Dir.  *
  666. ******************************************************************************/
  667. CagdVecStruct *CagdSrfTangent(CagdSrfStruct *Srf, CagdRType u, CagdRType v,
  668.                                 CagdSrfDirType Dir)
  669. {
  670.     switch (Srf -> GType) {
  671.     case CAGD_SBEZIER_TYPE:
  672.         return BzrSrfTangent(Srf, u, v, Dir);
  673.     case CAGD_SBSPLINE_TYPE:
  674.         return BspSrfTangent(Srf, u, v, Dir);
  675.     case CAGD_SPOWER_TYPE:
  676.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  677.         return NULL;
  678.     default:
  679.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  680.         return NULL;
  681.     }
  682. }
  683.  
  684. /******************************************************************************
  685. * Given a srf and parameter values u,v, returns the surface normal at u,v.    *
  686. ******************************************************************************/
  687. CagdVecStruct *CagdSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
  688. {
  689.     switch (Srf -> GType) {
  690.     case CAGD_SBEZIER_TYPE:
  691.         return BzrSrfNormal(Srf, u, v);
  692.     case CAGD_SBSPLINE_TYPE:
  693.         return BspSrfNormal(Srf, u, v);
  694.     case CAGD_SPOWER_TYPE:
  695.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  696.         return NULL;
  697.     default:
  698.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  699.         return NULL;
  700.     }
  701. }
  702.  
  703. /******************************************************************************
  704. * Return a new reversed surface by reversing in U direction the control mesh. *
  705. ******************************************************************************/
  706. CagdSrfStruct *CagdSrfReverse(CagdSrfStruct *Srf)
  707. {
  708.     CagdBType
  709.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  710.     int i, Len, Row, Col,
  711.     ULength = Srf -> ULength,
  712.     VLength = Srf -> VLength,
  713.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  714.     CagdSrfStruct
  715.     *ReversedSrf = CagdSrfCopy(Srf);
  716.     CagdRType *KV,
  717.     **Points = ReversedSrf -> Points;
  718.  
  719.     switch (Srf -> GType) {
  720.     case CAGD_SBEZIER_TYPE:
  721.     case CAGD_SBSPLINE_TYPE:
  722.         break;
  723.     case CAGD_SPOWER_TYPE:
  724.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  725.         return NULL;
  726.     default:
  727.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  728.         return NULL;
  729.     }
  730.  
  731.     /* Reverse the Mesh: */
  732.     Len = ULength / 2;
  733.     for (Row = 0; Row < VLength; Row++)
  734.     for (Col = 0; Col < Len; Col++)
  735.         for (i = IsNotRational; i <= MaxCoord; i++)
  736.         SWAP(CagdRType,
  737.              Points[i][Row * ULength + Col],
  738.              Points[i][Row * ULength + ULength - Col - 1]);
  739.  
  740.     /* Reverse the U knot vector if it exists: */
  741.     if (Srf -> GType == CAGD_SBSPLINE_TYPE &&
  742.     Srf -> UKnotVector != NULL) {
  743.     KV = BspKnotReverse(Srf -> UKnotVector, Srf -> UOrder + ULength);
  744.     IritFree((VoidPtr) ReversedSrf -> UKnotVector);
  745.     ReversedSrf -> UKnotVector = KV;
  746.     }
  747.  
  748.     return ReversedSrf;
  749. }
  750.  
  751. /******************************************************************************
  752. * Return a new reversed surface by flipping the U and V directions.           *
  753. ******************************************************************************/
  754. CagdSrfStruct *CagdSrfReverse2(CagdSrfStruct *Srf)
  755. {
  756.     CagdBType
  757.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  758.     int i, Row, Col,
  759.     ULength = Srf -> ULength,
  760.     VLength = Srf -> VLength,
  761.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  762.     CagdSrfStruct
  763.     *ReversedSrf = CagdSrfCopy(Srf);
  764.     CagdRType
  765.     **Points = Srf -> Points,
  766.     **RevPoints = ReversedSrf -> Points;
  767.  
  768.     switch (Srf -> GType) {
  769.     case CAGD_SBEZIER_TYPE:
  770.     case CAGD_SBSPLINE_TYPE:
  771.         break;
  772.     case CAGD_SPOWER_TYPE:
  773.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  774.         return NULL;
  775.     default:
  776.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  777.         return NULL;
  778.     }
  779.  
  780.     /* Reverse the Mesh: */
  781.     for (Row = 0; Row < VLength; Row++)
  782.     for (Col = 0; Col < ULength; Col++)
  783.         for (i = IsNotRational; i <= MaxCoord; i++)
  784.         RevPoints[i][Col * VLength + Row] =
  785.             Points[i][Row * ULength + Col];
  786.  
  787.     /* Swap the U and the V knot vectors if the exists: */
  788.     if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
  789.     SWAP(CagdRType *,
  790.          ReversedSrf -> UKnotVector, ReversedSrf -> VKnotVector);
  791.     }
  792.  
  793.     /* And swap the orders and lengths. */
  794.     SWAP(int, ReversedSrf -> UOrder, ReversedSrf -> VOrder);
  795.     SWAP(int, ReversedSrf -> ULength, ReversedSrf -> VLength);
  796.  
  797.     return ReversedSrf;
  798. }
  799.